package socket;

import java.io.*;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;

/**聊天室客户端*/
public class Client {
    private Socket socket;//套接字,封装Tcp协议细节  与远端TCP建立连接

    public Client(){
        /*
        *
        Socket封装了TCP协议的通讯细节,使用它就可以与远端计算机建立TCP连接.并基于两个流(一个输入
        一个输出)与远端计算机进行双向通讯
        将Socket比喻为是一部手机
     */
        try {
            System.out.println("正在连接服务器...");
            /*实例化的过程就是连接的过程  176.201.106.55
            * Socket实例化需要传入两个参数
             * 参数1:服务端的地址信息
             * 参数2:服务端打开的服务端口号
             * 客户端通过服务端的地址找到网络上的服务器计算机,通过端口可以
             * 建立TCP连接*/
            socket = new Socket("176.201.106.59",8088);//localhost:本机地址
            System.out.println("与服务端建立连接!");
        } catch (IOException e) {
            e.printStackTrace();//java.net.ConnectException: Connection refused: connect   端口未被占用无法连接
        }
    }
    public void start(){//客户端开始工作
        //将读取来自服务端消息的线程启动起来
        ServerHandler serverHandler =new ServerHandler();
        Thread receiveMessage = new Thread(serverHandler);
        receiveMessage.setDaemon(true);
        receiveMessage.start();
        //客户端向服务端发送数据,则需要使用socket获取输出流  封装与多态
        try {
            OutputStream out = socket.getOutputStream();//低级流
//            ObjectOutputStream oos = new ObjectOutputStream(out);
            OutputStreamWriter osw = new OutputStreamWriter(out, StandardCharsets.UTF_8);//转换流,将字符转化为2进制
            BufferedWriter bw = new BufferedWriter(osw);//缓冲流,将其转化为char[]字符
            PrintWriter pw = new PrintWriter(bw,true);//字符流,按行输出,自动行刷新

            Scanner scanner = new Scanner(System.in);
            String line;
            while (true){
                line = scanner.nextLine();
                if ("exit".equals(line)){
                    break;
                }
                pw.println(line);
            }
//            pw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                /*高级流在内存进行操作
                * Socket的close方法里封装了与服务端4次挥手操作.与服务端断开连接.
                    并且该close还会在内部将通过socket获取的输入流与输出流关闭.*/
                socket.close();//四次挥手
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

         //客户端获取服务端数据
       /* try {
            InputStream is = socket.getInputStream();
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader br = new BufferedReader(isr);
            String line;
            if ((line = br.readLine())!= null){
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }*/


    }

    public static void main(String[] args) {//程序启动(静态方法)
        Client client = new Client();
        client.start();
    }

    //输出线程
    private class ServerHandler implements Runnable{
        @Override
        public void run() {
            try {
                //客户端获取服务端数据
                InputStream is = socket.getInputStream();
                InputStreamReader isr = new InputStreamReader(is,StandardCharsets.UTF_8);
                BufferedReader br = new BufferedReader(isr);
                String line;
                while ((line = br.readLine())!= null){
                    System.out.println(line);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
